#ifndef CHBOT_H
#define CHBOT_H

#include <QFile>
#include <QHostAddress>
#include <QString>
#include <QTextStream>
#include <QTime>
#include <QVector>

#include "bnet.h"
#include "db.h"
#include "singleton.h"

// Error codes

#define HBOTCLASS_ERROR_SUCCESS									0

#define HBOTCLASS_ERROR_DATABASE_SQLITE_FILENAMEEMPTY			1
#define HBOTCLASS_ERROR_DATABASE_SQLITE_FILENAMEINVALID			2
#define HBOTCLASS_ERROR_DATABASE_SQLITE_ERROR					3

#define HBOTCLASS_ERROR_DATABASE_MYSQL_SERVEREMPTY				4
#define HBOTCLASS_ERROR_DATABASE_MYSQL_DATABASEEMPTY			5
#define HBOTCLASS_ERROR_DATABASE_MYSQL_USEREMPTY				6
#define HBOTCLASS_ERROR_DATABASE_MYSQL_PORTEMPTY				7
#define HBOTCLASS_ERROR_DATABASE_MYSQL_PORTINVALID				8
#define HBOTCLASS_ERROR_DATABASE_MYSQL_ERROR					9

// Error strings

#define HBOTCLASS_ERRORSTRING_DATABASE_SQLITE_FILENAMEEMPTY		"Error: SQLite Field <b>Database::Database File</b> in the Database tab of the profile manager must not be empty. Please change this to a non-empty string and reload the profile."
#define HBOTCLASS_ERRORSTRING_DATABASE_SQLITE_FILENAMEINVALID	"Error: SQLite Field <b>Database::Database File</b> in the Database tab of the profile manager must not contain any of the following characters: \\ / : * ? \" &#60; &#62; | Please change this to a valid string and reload the profile."

#define HBOTCLASS_ERRORSTRING_DATABASE_MYSQL_SERVEREMPTY		"Error: MySQL Field <b>Database::Server</b> in the Database tab of the profile manager must not be empty. Please change this to a non-empty string and reload the profile."
#define HBOTCLASS_ERRORSTRING_DATABASE_MYSQL_DATABASEEMPTY		"Error: MySQL Field <b>Database::Database</b> in the Database tab of the profile manager must not be empty. Please change this to a non-empty string and reload the profile."
#define HBOTCLASS_ERRORSTRING_DATABASE_MYSQL_USEREMPTY			"Error: MySQL Field <b>Database::User</b> in the Database tab of the profile manager must not be empty. Please change this to a non-empty string and reload the profile."
#define HBOTCLASS_ERRORSTRING_DATABASE_MYSQL_PORTEMPTY			"Error: MySQL Field <b>Database::Port</b> in the Database tab of the profile manager must not be empty. Please change this to a non-empty string and reload the profile."
#define HBOTCLASS_ERRORSTRING_DATABASE_MYSQL_PORTINVALID		"Error: MySQL Field <b>Database::Port</b> in the Database tab of the profile manager must be in a range of 0-65535. Please change this to a proper port number and reload the profile."

// Logging values

#define LOGGING_DISABLED										0
#define LOGGING_METHOD_1										1
#define LOGGING_METHOD_2										2
#define LOGGING_FILE_EMPTY										3

// Version

#define HBOT_VERSION											"0.0.2"

// Operation Threads

#define NUM_OP_THREADS_X										2

class OperationThread;

class CHBot: public Singleton<CHBot>
{
private:
	bool m_Exiting;
	bool m_ExitingNice;
	bool m_UsingTFT;

	int m_DatabaseType; /* -1 = Invalid | 0 = SQLite | 1 = MySQL */
	int m_Error;
	int m_LogMethod;

	CDatabase *m_Database;
	OperationThread *m_OperationThreadsLowPriority[NUM_OP_THREADS_X];
	OperationThread *m_OperationThreadsNormalPriority[NUM_OP_THREADS_X];
	QFile *m_LogDevice;
	QList<QHostAddress> m_LocalAddresses;
	QString m_LogFile;
	QString m_Profile;
	QTextStream *m_Log;
	QTime m_Time;
	QVector<CBNet *> m_BNets;

public:
	CHBot(const QString &profile);
	~CHBot();

	QVector<int> GetNumberBnet();

	bool GetExiting() const															{ return m_Exiting; }
	int GetDatabaseType() const														{ return m_DatabaseType; }
	int GetError() const															{ return m_Error; }
	int GetLogMethod() const														{ return m_LogMethod; }
	CDatabase *GetDatabase() const													{ return m_Database; }
	QFile *GetLogDevice() const														{ return m_LogDevice; }
	QString GetLogFile() const														{ return m_LogFile; }
	QTextStream *GetLog() const														{ return m_Log; }
	QTime GetTime() const															{ return m_Time; }
	QVector<CBNet *> GetBNet()														{ return m_BNets; }

	void SetExiting(bool exiting)													{ m_Exiting = true; }
	void SetExitingNice(bool exiting)												{ m_ExitingNice = true; }
	void SetLogMethod(int logMethod)												{ m_LogMethod = logMethod; }
};

void SignalInt(int s);
void SignalInt2(int s);
unsigned int GetMilliseconds();
unsigned int GetSeconds();

#endif // CHBOT_H
